package com.Volatile;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 1.在单线程下，不管怎么重排序，执行结果不会被改变。
 *
 * 2. 但是在多线程下，就不能保证了。
 */
public class 禁止指令重排序 {

    public static void main(String[] args) {

        int[] a = {1,2,3};

//        List<int[]> ints = Arrays.asList(a);

//        List<Integer> integers = Arrays.asList(1, 2, 3);
        Integer[] b = {1,3};
        List<Integer> collect = Arrays.stream(b).collect(Collectors.toList());

        List<Integer> collect1 = Arrays.stream(a).boxed().collect(Collectors.toList());

    }

}

/**
 * 不加 volatile ，对象在创建的过程中，导致对象没有初始化而被其他线程获取到使用，又可能又为空到风险
 *
 * 1.分配内存空间。
 * 2.调用构造器，初始化实例。
 * 3.返回地址给引用
 *
 * volatile
 *
 * 一. 可见性
 *  1. cpu 在变量赋值之后加上写屏障，使得对volatile变量以及之前对变量的对写都写入到主内存中
 *  2. cpu 在读变量之前加上读屏障，使得对volatile变量以及之后的变量的读都从主内存中读取
 *
 * 二. 禁止指令重排序
 *  1. 写屏障禁止volatile写指令之前的指令排到该写指令之后
 *  2. 读屏障禁止volatile读指令之后的指令排到写指令之前
 *
 *
 */


class Factory{

//    private static volatile Factory factory;

    private Factory(){

    }

    private static class SingleFactory{

        private static final Factory factory = new Factory();
    }

    public static  Factory getInstance(){


//        if (factory == null){
//
//            synchronized(Factory.class){
//
//                /**
//                 * 这里做判断是防止在初始化factory的时候，有两个线程进入，其中一个线程进入创建factory实例
//                 * 另外一个线程block在synchronized处，当第一个进入的线程解锁后，另外一个线程进入，这时factory以及创建成功，不需要再创建
//                 */
//                if (factory == null){
//
//                    factory = new Factory();
//                }
//            }
//        }

        return  SingleFactory.factory;
    }

}
